#include <xdevice/consensus.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 简单的设备存储结构
typedef struct device_storage {
    char name[XDEVICE_MAX_DEVICE_NAME];
    uint64_t size;
    char* data;
    struct device_storage* next;
} device_storage_t;

struct xdevice_consensus {
    char data_dir[XDEVICE_MAX_PATH_LEN];
    int node_id;
    int cluster_size;
    bool started;
    device_storage_t* devices;  // 设备链表
};

xdevice_consensus_t* xdevice_consensus_create(const char* data_dir, int node_id, int cluster_size) {
    if (!data_dir || node_id < 0 || cluster_size <= 0) {
        return NULL;
    }
    
    xdevice_consensus_t* consensus = calloc(1, sizeof(xdevice_consensus_t));
    if (!consensus) {
        return NULL;
    }
    
    strncpy(consensus->data_dir, data_dir, sizeof(consensus->data_dir) - 1);
    consensus->node_id = node_id;
    consensus->cluster_size = cluster_size;
    consensus->started = false;
    consensus->devices = NULL;  // 初始化设备链表
    
    return consensus;
}

void xdevice_consensus_destroy(xdevice_consensus_t* consensus) {
    if (consensus) {
        // 清理所有设备存储
        device_storage_t* current = consensus->devices;
        while (current) {
            device_storage_t* next = current->next;
            free(current->data);
            free(current);
            current = next;
        }
        free(consensus);
    }
}

// 查找设备存储的辅助函数
static device_storage_t* find_device(xdevice_consensus_t* consensus, const char* name) {
    if (!consensus || !name) return NULL;
    
    device_storage_t* current = consensus->devices;
    while (current) {
        if (strcmp(current->name, name) == 0) {
            return current;
        }
        current = current->next;
    }
    return NULL;
}

int xdevice_consensus_start(xdevice_consensus_t* consensus) {
    if (!consensus) {
        return XDEVICE_CORE_ERROR_INVALID_PARAM;
    }
    
    consensus->started = true;
    return XDEVICE_CORE_OK;
}

int xdevice_consensus_stop(xdevice_consensus_t* consensus) {
    if (!consensus) {
        return XDEVICE_CORE_ERROR_INVALID_PARAM;
    }
    
    consensus->started = false;
    return XDEVICE_CORE_OK;
}

/* 设备操作API实现 */
int xdevice_consensus_create_device(xdevice_consensus_t* consensus, const char* name, uint64_t size, xdevice_storage_type_t storage_type) {
    if (!consensus || !name) {
        return XDEVICE_CORE_ERROR_INVALID_PARAM;
    }
    
    printf("[Consensus] 创建设备请求: %s, 大小: %lu, 存储类型: %d\n", name, size, storage_type);
    
    // 检查设备是否已存在
    if (find_device(consensus, name)) {
        return XDEVICE_CORE_ERROR_EXISTS;
    }
    
    // 创建新设备存储
    device_storage_t* device = calloc(1, sizeof(device_storage_t));
    if (!device) {
        return XDEVICE_CORE_ERROR_OUT_OF_MEMORY;
    }
    
    strncpy(device->name, name, sizeof(device->name) - 1);
    device->size = size;
    device->data = calloc(1, size);
    if (!device->data) {
        free(device);
        return XDEVICE_CORE_ERROR_OUT_OF_MEMORY;
    }
    
    // 添加到设备链表
    device->next = consensus->devices;
    consensus->devices = device;
    
    // TODO: 在多实例集群中，这里应该通过Raft协议同步设备创建操作到所有实例
    // 现在先使用简单的同步方式
    printf("[Consensus] 设备在共识层创建成功: %s\n", name);
    
    return XDEVICE_CORE_OK;
}

int64_t xdevice_consensus_read(xdevice_consensus_t* consensus, const char* name, uint64_t offset, void* buffer, size_t length) {
    if (!consensus || !name || !buffer) {
        return XDEVICE_CORE_ERROR_INVALID_PARAM;
    }
    
    printf("[Consensus] 读取请求: %s, 偏移: %lu, 长度: %zu\n", name, offset, length);
    
    // 查找设备
    device_storage_t* device = find_device(consensus, name);
    if (!device) {
        printf("[Consensus] 设备不存在: %s\n", name);
        return XDEVICE_CORE_ERROR_NOT_FOUND;
    }
    
    // 检查偏移和长度
    if (offset >= device->size) {
        printf("[Consensus] 偏移超出设备大小: %lu >= %lu\n", offset, device->size);
        return 0;
    }
    
    size_t available = device->size - offset;
    if (length > available) {
        length = available;
    }
    
    // 复制数据
    memcpy(buffer, device->data + offset, length);
    printf("[Consensus] 成功读取 %zu 字节\n", length);
    
    return length;
}

int64_t xdevice_consensus_write(xdevice_consensus_t* consensus, const char* name, uint64_t offset, const void* buffer, size_t length) {
    if (!consensus || !name || !buffer) {
        return XDEVICE_CORE_ERROR_INVALID_PARAM;
    }
    
    printf("[Consensus] 写入请求: %s, 偏移: %lu, 长度: %zu\n", name, offset, length);
    
    // 查找设备
    device_storage_t* device = find_device(consensus, name);
    if (!device) {
        printf("[Consensus] 设备不存在: %s\n", name);
        return XDEVICE_CORE_ERROR_NOT_FOUND;
    }
    
    // 检查偏移和长度
    if (offset >= device->size) {
        printf("[Consensus] 偏移超出设备大小: %lu >= %lu\n", offset, device->size);
        return 0;
    }
    
    size_t available = device->size - offset;
    if (length > available) {
        length = available;
    }
    
    // 复制数据
    memcpy(device->data + offset, buffer, length);
    printf("[Consensus] 成功写入 %zu 字节\n", length);
    
    return length;
}

int xdevice_consensus_sync(xdevice_consensus_t* consensus, const char* name) {
    if (!consensus || !name) {
        return XDEVICE_CORE_ERROR_INVALID_PARAM;
    }
    
    printf("[Consensus] 同步请求: %s\n", name);
    
    // 简化实现：暂时直接返回成功
    // TODO: 在有存储上下文后重新实现
    return XDEVICE_CORE_OK;
}

int xdevice_consensus_get_cluster_info(xdevice_consensus_t* consensus, xdevice_cluster_info_t* info) {
    if (!consensus || !info) {
        return XDEVICE_CORE_ERROR_INVALID_PARAM;
    }
    
    printf("[Consensus] 获取集群信息\n");
    
    // 简化实现：填充基本信息
    info->node_count = consensus->cluster_size;
    info->leader_id = consensus->node_id;
    info->current_term = 1;
    info->commit_index = 0;
    info->is_healthy = true;
    
    return XDEVICE_CORE_OK;
}

int xdevice_consensus_list_devices(xdevice_consensus_t* consensus, char names[][XDEVICE_MAX_DEVICE_NAME], int max_count) {
    if (!consensus || !names) {
        return XDEVICE_CORE_ERROR_INVALID_PARAM;
    }
    
    printf("[Consensus] 列出设备\n");
    
    int count = 0;
    device_storage_t* current = consensus->devices;
    while (current && count < max_count) {
        size_t len = strlen(current->name);
        if (len >= XDEVICE_MAX_DEVICE_NAME) {
            len = XDEVICE_MAX_DEVICE_NAME - 1;
        }
        memcpy(names[count], current->name, len);
        names[count][len] = '\0';
        current = current->next;
        count++;
    }
    
    return count;
}
